<template>
  <div class="main-container">
    <div id="drawArea" ref="drawArea"></div>
    <div class="toolbar">
      <div class="fileSelector">
        <input type="file" @change="openTreeFile" />
        <el-button type="primary" @click="test" size="mini">测试</el-button>
        <el-button type="primary" @click="drawGeoByPath('geometry.root/default;1')" size="mini">Draw</el-button>
        <el-button type="primary"
          @click="drawGeoByPath('geometry.root/default;1/world_volume/MultiLayerDriftChamber02_Gas_2')"
          size="mini">DrawMDC
        </el-button>
        <el-button type="primary" @click="drawGeoByPath('geometry.root/default;1/world_volume/InnerTracker_Gas_1')"
          size="mini">DrawITK
        </el-button>
        <el-button type="primary" @click="drawGeoByPath('geometry.root/default;1/world_volume/DetectorMUC_10')"
          size="mini">DrawMUD
        </el-button>
        <el-button type="primary" @click="drawGeoByPath('geometry.root/default;1/world_volume/STCF')" size="mini">DrawECAL
        </el-button>
      </div>
      <div class="controls">
        <el-select v-model="selectHelix" filterable placeholder="请选择" value-key="uuid" @change="selectHelixChange">
          <el-option v-for="(item, index) in helixStore" :key="item.uuid" :label="'Line' + index" :value="item">
          </el-option>
        </el-select>
        <el-button @click="changeWireFrame" type="primary">wireframe</el-button>
      </div>
    </div>
  </div>
</template>

<script type="module">
import { openFile, draw, registerForResize, cleanup, HierarchyPainter } from "jsroot";
import { TSelector, treeProcess } from "jsroot/tree";
import { rawMap, recMap } from "@/utils/maping";
import { detectorArray } from "@/utils/array"
import * as THREE from "jsroot/three";

export default {
  name: 'HomeView',
  data() {
    return {
      branches: {},//存储branch内容
      treeFile: null,//存储树文件
      Tpainter: null,//存储事例对象
      helix: null,//螺旋线Object对象
      helixStore: [],//螺旋线Object对象存储
      helixPosition: [],///螺旋点对应坐标
      intersects: [],//选中的螺旋线
      allIntersects: [],//选中的所有物体
      selectHelix: null,//选中的螺旋线
      lastSelectHelix: null,//上一次选中的螺旋线
    }
  },
  mounted() {

  },
  methods: {
    /**  打开树文件
     * @param {File} e - dom对象
     * @return {Promise<void>}
     */
    async openTreeFile(e) {
      //保存this
      const _this = this;
      //计数器
      let cnt = 0;
      //解析Tree文件
      this.treeFile = await openFile(e.target.files[0]);
      const tree = await this.treeFile.readObject("events;1");
      //创建TSelector对象
      const selector = new TSelector();
      tree.fBranches.arr.forEach(item => {
        selector.addBranch(item.fName);
      })
      //解析branches数据过程
      selector.Begin = function (tree) {
      }
      selector.Process = function (index) {
        this._branches.forEach(name => {
          if (!_this.branches[name]) {
            _this.branches[name] = [];
          }
          _this.branches[name].push([].concat(this.tgtobj[name]))
        })
        cnt++;
      }
      selector.Terminate = function (res) {
        console.log(cnt);
      }
      //执行解析branches过程
      await treeProcess(tree, selector)
      console.log(this.branches);
    },
    /** 更改网状结构 */
    changeWireFrame() {
      this.Tpainter.ctrl.wireframe = !this.Tpainter.ctrl.wireframe;
      let on = this.Tpainter.ctrl.wireframe;
      this.Tpainter._scene.traverse(obj => this.Tpainter.accessObjectWireFrame(obj, on));
      this.Tpainter.render3D(0, true);
    },
    /** 根据事例路径绘制对应图像
     * @param {string} path - 事例文件路径
     */
    async drawGeoByPath(path) {
      //点 or 线
      let flag = 0;
      const a = 333.564;
      const _this = this;
      let energyArray = [];
      const staves = 133, rows = 51;
      // 初始化二维数组，将所有元素设置为 0
      for (let i = 0; i < staves; i++) {
        energyArray[i] = [];
        for (let j = 0; j < rows; j++) {
          energyArray[i][j] = 0;
        }
      }
      //清空重绘
      cleanup("drawArea");
      //获取事例数据以及文件结构
      const geoFile = await openFile("geometry.root")
      const hpainter = new HierarchyPainter('root', null);
      hpainter.h = hpainter.fileHierarchy(geoFile)
      const geoName = path.substring(path.lastIndexOf('/') + 1);
      let node;
      if (geoName === 'STCF') {
        node = await hpainter.expandItem(path + 'BEMC_7')
      } else {
        //获取对应路径的事例
        node = await hpainter.expandItem(path);
      }
      //绘制事例图像
      if (node._readobj) {
        this.Tpainter = await draw("drawArea", node._readobj);
      } else if (node._volume)
        this.Tpainter = await draw("drawArea", node._volume);
      //console.log(node)
      //创建点材质
      const pointMaterial = new THREE.PointsMaterial({ color: 'red', size: 10 });
      //创建线材质
      const lineMaterial = new THREE.LineBasicMaterial({ color: 'red' });
      //获取碰撞点
      const positions = [];
      let cnt = 0;
      const detailInfo = [];
      let num = 0, min = 0, max = 0;
      for (let name in this.branches) {
        if (this.treeFile.getFileName() === '1_fullrec.root') { 
          if (name.includes(rawMap.get(geoName)) && detectorArray.includes(name)) {
            // console.log("name",name)
            this.branches[name].forEach(arr => {
              arr.forEach(item => {
                // if (item.position !== undefined) {
                  if (name.includes('RecECALHitCol')) {
                    console.log("okk");
                    if (node._name === 'default;1') {
                      positions.push(item.position.x, item.position.y, item.position.z)
                    }
                    if (node._name === 'STCFBEMC_7') {
                      let crystalName = this.GetCryName(item.crystalID);
                      //有stave击中
                      if (crystalName !== undefined) {
                        let arr = crystalName.split("/");
                        if (arr[0] === 'STCFBEMC_7') {
                          let energy = item.energy;
                          let staveNum = parseInt(arr[1].substring(arr[1].lastIndexOf('_') + 1)) + 1;
                          let rowNum = parseInt(arr[2].substring(arr[2].lastIndexOf('_') + 1));
                          energyArray[staveNum][rowNum] += energy;
                          if (energyArray[staveNum][rowNum] > 0) {
                            if (min === 0) {
                              min = energyArray[staveNum][rowNum];
                            }
                            if (min !== 0 && min > energyArray[staveNum][rowNum]) {
                              min = energyArray[staveNum][rowNum];
                            }
                            if (energyArray[staveNum][rowNum] > max) {
                              max = energyArray[staveNum][rowNum];
                            }
                          }
                          //this.Tpainter._toplevel.children[0].children[staveNum].children[rowNum].children[0].material.color = new THREE.Color(1.0,0.0,0.0);
                          //console.log(staveNum + "_" + rowNum);
                          num++;
                        }
                      }
                    }
                    //console.log(crystalName);
                  } else {
                    positions.push(item.position.x * 0.1, item.position.y * 0.1, item.position.z * 0.1)
                  }
                  // console.log("position", item.position.x, item.position.y, item.position.z);
                  //console.log(item);
                  cnt++
                // }
                if (item.posIn !== undefined) {
                  positions.push(item.posIn.x * 0.1, item.posIn.y * 0.1, item.posIn.z * 0.1)
                  // console.log("position", item.position.x, item.position.y, item.position.z);
                  //console.log(name);
                  cnt++
                }
              })
            })
          }
        } else { //重建数据
          if (name.includes(recMap.get(geoName))) {
            flag = 1;
            this.branches[name].forEach(arr => {
              arr.forEach(item => {
                //先这样设置，具体的属性暂未确定
                if (item.d0 !== undefined && item.phi0 !== undefined && item.kap !== undefined && item.tanlamda !== undefined && item.z0 !== undefined) {
                  //console.log(item);
                  const tempPosition = [];
                  tempPosition.push(item.posFirst.x, item.posFirst.y, item.posFirst.z);
                  for (let i = 0; i < 100; i++) {
                    let x, y, z
                    //console.log(x)
                    //first为起始, last结束
                    if (item.kap < 0) {
                      x = item.posFirst.x + ((item.d0 * Math.cos(item.phi0)) + (a / item.kap * (Math.cos(item.phi0) - Math.cos(item.phi0 + 0.5 * Math.PI / 100 * i))));
                      y = item.posFirst.y + ((item.d0 * Math.sin(item.phi0)) + (a / item.kap * (Math.sin(item.phi0) - Math.sin(item.phi0 + 0.5 * Math.PI / 100 * i))));
                      z = item.posFirst.z + (item.z0 - (a / item.kap * (0.5 * Math.PI / 100 * i) * item.tanlamda));
                    } else {
                      x = item.posFirst.x + ((item.d0 * Math.cos(item.phi0)) + (a / item.kap * (Math.cos(item.phi0) - Math.cos(item.phi0 - 0.5 * Math.PI / 100 * i))));
                      y = item.posFirst.y + ((item.d0 * Math.sin(item.phi0)) + (a / item.kap * (Math.sin(item.phi0) - Math.sin(item.phi0 - 0.5 * Math.PI / 100 * i))));
                      z = item.posFirst.z + (item.z0 - (a / item.kap * (0.5 * Math.PI / 100 * i) * item.tanlamda));
                    }
                    if(x*x+y*y<100*100+30*30){
                      tempPosition.push(x,y,z)
                    }else{
                      break
                    }
                  }
                  //tempPosition.push(item.posLast.x, item.posLast.y, item.posLast.z);
                  if (tempPosition.length) {
                    _this.helixPosition.push(tempPosition);
                    detailInfo.push({
                      trackId: detailInfo.length,
                      momFirst: item.momFirst,
                      momLast: item.momLast,
                      momPOCA: item.momPOCA,
                      posFirst: item.posFirst,
                      posLast: item.posLast,
                      d0: item.d0,
                      phi0: item.phi0,
                      kap: item.kap,
                      tanlamda: item.tanlamda,
                      z0: item.z0
                    })
                    cnt++
                  }
                }
              })
            })
          }
        }
      }
      // 颜色分布
      if (node._name === 'STCFBEMC_7') {
        console.log('min==' + min + 'max==' + max);
        for (let i = 1; i < staves; i++) {
          for (let j = 0; j < rows; j++) {
            if (energyArray[i][j] !== 0) {
              // 将颜色范围确定在 0 - 1 之间
              let colorNum = (energyArray[i][j] - min) / (max - min);
              this.Tpainter._toplevel.children[0].children[i].children[j].children[0].material.color = new THREE.Color(1.0, colorNum, 0);
            }
          }
        }
      }
      //console.log(cnt);
      console.log("this.helixPosition",this.helixPosition);
      //console.log("detailInfo", detailInfo);
      console.log(num)
      this.Tpainter._toplevel.add(new THREE.Object3D())
      this.helix = this.Tpainter._toplevel.children[1]
      
      //绘制点/线
      if (flag) {
        this.helixPosition.forEach((positions, index) => {
          let geometry = new THREE.BufferGeometry();
          geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
          let line = new THREE.Line(geometry, lineMaterial);
          line.tip = detailInfo[index];
          this.helixStore.push(line)
        })

      } else {
        console.log("绘制点")
        //console.log(positions)
        //通过事例对象添加点
        const geometry = new THREE.BufferGeometry();
        geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
        const points = new THREE.Points(geometry, pointMaterial);
        this.Tpainter._toplevel.add(points)
      }
      console.log("helix", this.helix);
      console.log("helixStore", this.helixStore);
      this.Tpainter.addOrbitControls()
      registerForResize("drawArea", 1000)
      this.Tpainter._renderer.domElement.addEventListener('mousemove', (function () {
        this.ProcessMouseMove()
      }).bind(this))
      console.log(this.Tpainter);

      console.log(THREE.RenderPass);
    },
    /**
     * 鼠标移动监听事件
     */
    ProcessMouseMove() {
      if (this.intersects.length) {
        // this.intersects.forEach(e => { e.object.material.color = new THREE.Color('red') })
        this.intersects[0].object.material.color = new THREE.Color('red')
      }
      this.intersects = this.Tpainter._controls.raycaster.intersectObjects(this.helix.children, false);
      //console.log("intersects", this.intersects);
      this.allIntersects = this.Tpainter._controls.raycaster.intersectObjects(this.Tpainter._scene.children, true);
      // console.log("allIntersects", this.allIntersects);
      if (this.intersects.length) {
        // this.intersects.forEach(e => { e.object.material.color = new THREE.Color('#79BEDF') })
        this.intersects[0].object.material.color = new THREE.Color('#79BEDF')
        this.Tpainter._controls.tooltip.show({ lines: this.tipToString(this.intersects[0].object.tip) }, this.Tpainter._controls.tmout_mouse)
        this.Tpainter._controls.tooltip.pos(this.Tpainter._controls.tmout_ttpos)
      }
      if (!this.allIntersects.length) {
        this.Tpainter._controls.tooltip.hide()
      }
      this.Tpainter.render3D(0);
    },
    /**
     * 选择绘制线
     * @param {Line} value
     */
    selectHelixChange(value) {
      this.helix.remove(this.lastSelectHelix)
      this.lastSelectHelix = value;
      this.helix.add(value)
    },
    /**
     * tip对象转换字符串
     * @param {Object} tip
     */
    tipToString(tip) {
      const res = [];
      res.push(`trackId=${tip.trackId}`)
      res.push(`momFirst x=${tip.momFirst.x} y=${tip.momFirst.y} z=${tip.momFirst.z}`)
      res.push(`momLast: x=${tip.momLast.x} y=${tip.momLast.y} z=${tip.momLast.z}`)
      res.push(`momPOCA: x=${tip.momPOCA.x} y=${tip.momPOCA.y} z=${tip.momPOCA.z}`)
      res.push(`posFirst x=${tip.posFirst.x} y=${tip.posFirst.y} z=${tip.posFirst.z}`)
      res.push(`posLast x=${tip.posLast.x} y=${tip.posLast.y} z=${tip.posLast.z}`)
      res.push(`d0=${tip.d0} phi0=${tip.phi0} kap=${tip.kap} tanlamda=${tip.tanlamda} z0=${tip.z0}`)
      return res;
    },
    /**
     * 根据CrystalId获取CryName的名字
     * @param {string} CrystalID
     */
    GetCryName(CrystalID) {
      let cryName;
      let M = parseInt(CrystalID / 100000);
      let R = parseInt((CrystalID % 100000) / 1000);
      let C = parseInt((CrystalID % 100000) % 1000);
      if (M === 3) {
        cryName = "STCFBEMC_7/stave_" + (C - 1).toString() + "/row" + (R).toString() + "_" + (R - 1).toString() + "/Bmodule05_4";
      }
      if (M === 2) {
        let index;
        if (R < 4) index = (R - 1) * 85 + C - 1;
        if (R > 3 && R < 7) index = (R - 4) * 105 + 255 + C - 1;
        if (R > 6 && R < 11) index = (R - 7) * 130 + 570 + C - 1;
        cryName = "STCFEEMC_8/Rightrow" + (R + 11).toString() + "_" + (index).toString() + "/LEmodule05_4";
      }
      if (M === 1) {
        let index;
        if (R < 4) index = (R - 1) * 85 + C - 1;
        if (R > 3 && R < 7) index = (R - 4) * 105 + 255 + C - 1;
        if (R > 6 && R < 11) index = (R - 7) * 130 + 570 + C - 1;
        cryName = "STCFEEMC_9/Leftrow" + (R + 11).toString() + "_" + (index).toString() + "/REmodule05_4";
      }
      //console.log(cryName);
      return cryName;
    },
    async test() {
      //获取事例数据以及文件结构
      const _this = this;
      const a = 333.564;
      const lineMaterial = new THREE.LineBasicMaterial({ color: 'red' });
      const geoFile = await openFile("geometry.root")
      const hpainter = new HierarchyPainter('root', null);
      hpainter.h = hpainter.fileHierarchy(geoFile)
      const mdc = await hpainter.expandItem("geometry.root/default;1/world_volume/MultiLayerDriftChamber02_Gas_2");
      // const ecal = await hpainter.expandItem("geometry.root/default;1/world_volume/STCFBEMC_7");
      const tpaiter1 = await draw("drawArea", mdc._volume);
      // const tpaiter2 = await draw("drawArea", ecal._volume);
      const TrackerHypoTrackCol = this.branches["TrackerHypoTrackCol"]

      // console.log(tpaiter2._toplevel.children[0]);
      // tpaiter1._toplevel.children[0].children.push(tpaiter2._toplevel.children[0]);
      console.log(tpaiter1);
      this.helix = tpaiter1._toplevel.children[0]
      TrackerHypoTrackCol.forEach(arr => {
        if (arr.length === 20) {
          const obj3d = new THREE.Object3D();
          for (let i = 0; i < 20; i += 5) {
            const item = arr[i]
            //先这样设置，具体的属性暂未确定
            if (item.d0 !== undefined && item.phi0 !== undefined && item.kap !== undefined && item.tanlamda !== undefined && item.z0 !== undefined) {
              //console.log(item);
              const tempPosition = [];
              tempPosition.push(item.posFirst.x, item.posFirst.y, item.posFirst.z);
              for (let i = 0; i < 100; i++) {
                    let x, y, z
                    //console.log(x)
                    //first为起始, last结束
                    if (item.kap < 0) {
                      x = item.posFirst.x + ((item.d0 * Math.cos(item.phi0)) + (a / item.kap * (Math.cos(item.phi0) - Math.cos(item.phi0 + 0.5 * Math.PI / 100 * i))));
                      y = item.posFirst.y + ((item.d0 * Math.sin(item.phi0)) + (a / item.kap * (Math.sin(item.phi0) - Math.sin(item.phi0 + 0.5 * Math.PI / 100 * i))));
                      z = item.posFirst.z + (item.z0 - (a / item.kap * (0.5 * Math.PI / 100 * i) * item.tanlamda));
                    } else {
                      x = item.posFirst.x + ((item.d0 * Math.cos(item.phi0)) + (a / item.kap * (Math.cos(item.phi0) - Math.cos(item.phi0 - 0.5 * Math.PI / 100 * i))));
                      y = item.posFirst.y + ((item.d0 * Math.sin(item.phi0)) + (a / item.kap * (Math.sin(item.phi0) - Math.sin(item.phi0 - 0.5 * Math.PI / 100 * i))));
                      z = item.posFirst.z + (item.z0 - (a / item.kap * (0.5 * Math.PI / 100 * i) * item.tanlamda));
                    }
                    if(x*x+y*y<100*100+30*30){
                      tempPosition.push(x,y,z)
                    }else{
                      break
                    }
              }
              const geometry = new THREE.BufferGeometry();
              geometry.setAttribute('position', new THREE.Float32BufferAttribute(tempPosition, 3));
              const line = new THREE.Line(geometry, lineMaterial);
              obj3d.add(line)
            }
          }
          _this.helixStore.push(obj3d)
        }
      })
      console.log(_this.helixStore);
    }
  }
}
</script>

<style lang="scss" scoped>
.main-container {
  height: 100%;
  display: flex;
  flex-direction: column;

  #drawArea {
    height: 80%;

    .fileSelector {
      position: absolute;
      top: 5px;
      left: 5px;
    }
  }

  .toolbar {
    border-top: 1px dashed black;
    display: flex;
    justify-content: space-between;

    .controls {
      .el-button {
        margin-left: 12px;
      }
    }
  }
}
</style>